package com.sghd.fight.module.game.service.room;

import com.sghd.common.utils.math.RandomUtils;
import com.sghd.fight.module.game.config.RobotConfig;
import com.sghd.fight.module.game.config.SkillConfig;
import com.sghd.fight.module.game.core.ChessBoard;
import com.sghd.fight.module.game.core.model.BattleSkill;
import com.sghd.fight.module.game.core.model.UnitState;
import com.sghd.fight.module.game.service.skill.effect.Effect;
import com.sghd.pojo.fight.game.ChessType;
import com.sghd.pojo.fight.game.UnitEnum;
import com.sghd.pojo.fight.game.UnitValue;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author frank
 * @date 2019-03-19 11:36
 * @desc
 **/
public class Robot extends Player {
    private Logger logger = LoggerFactory.getLogger(getClass());
    /** 棋盘*/
    private ChessBoard chessBoard;
    private RobotConfig config;

    public Robot(long playerId, String name, int index, IRoom room, Map<Integer, Integer> level2Skill, Map<ChessType, Integer> element2Level, RobotConfig config) {
        super(playerId, name, index, room, level2Skill, element2Level, 0);
        this.type = UnitEnum.ROBOT;
        this.chessBoard = room.getChessBoard();
        this.config = config;
    }

    /** 上一次是否是放技能*/
    private long lastSkill;

    /**
     */
    @Override
    public void action() {
        if (room.isOver()) {
            return;
        }
        if (room.getCurrent() != this) {
            return;
        }
        int delay = RandomUtils.betweenInt(2000, 5000, true);
        if (room.getNextRound().hasState(UnitState.TRUSTEE)) {
            //另一个玩家托管，防止服务器逻辑跑太快
            delay = room.getConfig().getRoundTime() - 5000;
            //上一次也是放技能，防止，连续放两个技能
        }
        addWork(now -> {
            doAction();
            if (getRound() > 0) {
                action();
            }
        }, new Date(System.currentTimeMillis() + delay));
    }

    List<BattleSkill> canUseSkills = new ArrayList<>();

    /**
     * 机器人执行逻辑
     */
    @Override
    public void doAction() {
        if (room.isOver()) {
            return;
        }
        if (room.getCurrent() != this || round <= 0) {
            return;
        }
        //TODO 能否执行技能
        //能
        //有一定机率执行技能，
        //从可以执行的技能中，随机执行一个
        //不能
        //寻找可消除的棋子，执行行消除

        //寻找能执行技能
        for (BattleSkill battleSkill : skills.values()) {
            SkillConfig skillConfig = room.getConfigService().getSkillConfig(battleSkill.getSkillId());
            //检查魔法值
            boolean canUse = canUse(skillConfig, battleSkill);
            boolean effecting = effecting(battleSkill);
            //如果不在冷中并且，魔法值足够
            if (battleSkill.isCanUse() && canUse && !notUse() && !effecting) {
                canUseSkills.add(battleSkill);
            }
        }
        //可执行技能
        if (!canUseSkills.isEmpty()) {
            if (RandomUtils.isHit(getRate())) {
                Collections.shuffle(canUseSkills);
                BattleSkill skill = canUseSkills.get(0);
                try {
                    //两次放技能的间隔大于5秒
                    if (System.currentTimeMillis() - lastSkill < 5000) {
                        canUseSkills.clear();
                        return;
                    } else {
                        room.execute(id, skill.getSkillId());
                        lastSkill = System.currentTimeMillis();
                    }
                } catch (Exception e) {
                    logger.error("机器人执行技能[{}]发生错误！", skill.getSkillId(), e);
                    normalAction();
                }
            } else {
                normalAction();
            }
            canUseSkills.clear();
            //不能执行技能，交换一次
        } else {
            normalAction();
        }
    }

    /**
     * 施放技能的概率
     * @return
     */
    public float getRate() {
        float rate = 1.0F * getValue(UnitValue.HP) / getValue(UnitValue.HP_MAX);
        if (rate >= 0.7) {
            return 0.3F;
        }
        if (rate >= 0.5 && rate < 0.7) {
            return 0.4F;
        }
        if (rate >= 0.3 && rate < 0.5) {
            return 0.5F;
        }
        if (rate < 0.3) {
            return 0.7F;
        }
        return 0.3F;
    }

    public boolean effecting(BattleSkill skill) {
        SkillConfig skillConfig = room.getConfigService().getSkillConfig(skill.getSkillId());
        Integer buffId = MapUtils.getInteger(skillConfig.getContext(), Effect.BUFF_ID);
        if (buffId == null) {
            return false;
        }
        if (buffs.containsKey(buffId)) {
            return true;
        }
        if (room.getNextRound().getBuffs().containsKey(buffId)) {
            return true;
        }
        return false;
    }

    public void normalAction() {
        List<List<Integer>> canEmlis = chessBoard.canElim(true);
        Collections.shuffle(canEmlis);
        List<Integer> elimit = canEmlis.get(0);
        try {
            room.action(id, elimit.get(0), elimit.get(1));
        } catch (Exception e) {
            logger.error("机器人交换棋子发生错误！", e.getMessage());
        }
    }

    public RobotConfig getConfig() {
        return config;
    }


    public boolean canUse(SkillConfig skillConfig, BattleSkill battleSkill) {
        Map<ChessType, Integer> expends = skillConfig.getExpends(battleSkill.getLevel());
        if (expends == null || expends.isEmpty()) {
            return false;
        }
        Map<ChessType, Integer> magics = magic.getMagics();
        for (ChessType type : expends.keySet()) {
            Integer value = expends.get(type);
            if (magics.get(type) < value) {
                //魔法值不足
                return false;
            }
        }
        return true;
    }
}
